package grafoS;

import java.util.ArrayList;
import javafx.application.Platform;

/**
 * Gcol is a program to help users to learn a little about graph coloring, in
 * this software, you can learn some coloring algorithms, and add your own
 * algorithm for coloring.You can also learn BFS and DFS search. This tool, also
 * support the .col format from DIMACS (Center for Discrete Mathematics and
 * Theoretical Computer Science), so you can import a big graph and use all the
 * algorithms. Copyright (C) <2015> Clóvis Daniel Souza Silva, Samuel Silva de
 * Souza, Professor Leonardo Sampaio Rocha.
 * 
* This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
* This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
* You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 * contact: projetoGrafos@gmail.com
 */
/**
 *
 * @author Daniel
 * @author Samuel
 */
/**
 * In this class we have the graph, and vectors to coloring. the matrix Grafo is
 * the adjacency matrix of the Graph. the vector of chars cor, is a vector for
 * BFS, where we define the colors of the vertex during the search. the vector
 * of integers corC, is where the color of the vertex as integers are stored.
 * the boolean go is to define if the graph is oriented(true) or
 * non-oriented(false). n is to define the total of vertex, m is to define the
 * total edges.
 */
public class Graph {

    private int Grafo[][];
    private char cor[];
    private int corC[];
    private boolean go = false;
    int n, m;

    /**
     * The constructor of Graph class, where the class is initialized. To
     * initialize, we just need the parameter with the total of vertex, so we
     * can create the matrix.
     *
     * @param totalVertices used to define the total number of vertices.
     */
    public Graph(int totalVertices) {
        Grafo = new int[totalVertices][totalVertices];
        cor = new char[totalVertices];
        corC = new int[totalVertices];
        n = totalVertices;
    }

    /**
     * Checks if in a vector "p" exists a integer "a"
     *
     * @param p any vector.
     * @param a any integer.
     * @return true if the integer is in the vector.
     */
    public boolean checkVector(int[] p, int a) {
        for (int i = 0; i < p.length; i++) {
            if (p[i] == a) {
                return true;
            }
        }
        return false;
    }

    /**
     * Return The matrix of adjacency
     *
     * @return A matrix of integers.
     */
    public int[][] getGrafo() {
        return Grafo;
    }

    /**
     * define the total of edges 'm'
     *
     * @param GO A boolean to define if the graph is non-oriented or oriented.
     */
    private void totalArestas(boolean GO) {
        for (int i = 0; i < Grafo.length; i++) {
            for (int j = 0; j < Grafo.length; j++) {
                if (Grafo[i][j] == 1) {
                    m++;
                }
            }
        }
        if (GO == false) {
            m = m / 2;
        }
    }

    /**
     * Return the density of the graph.
     *
     * @return return the total of edges.
     */
    public int densidade() {
        return m;
    }

    /**
     * print the graph on console.
     */
    public void print() {
        System.out.println();
        System.out.printf("         | 1 | ");
        for (int i = 1; i < Grafo.length; i++) {
            System.out.printf("%d | ", i + 1);
        }
        System.out.println();
        for (int i = 0; i < Grafo.length; i++) {
            System.out.printf("Ponto %d :| ", i + 1);
            for (int j = 0; j < Grafo.length; j++) {
                System.out.printf("%d | ", Grafo[i][j]);
            }
            System.out.println();
        }
    }

    /**
     * return a string of the matrix of the graph, witch one can be used to put
     * the print in a textBox.
     *
     * @param console used to set the interface's text area.
     * @param sC used to keep the string in the console.
     * @param t used to select the tab.
     * @return a string equals the method print().
     */
    public String returnGrafo(javafx.scene.control.TextArea console, ArrayList<String> sC, int t) {
        String Aux = null;
        Aux = "\n";
        Integer intAux;
        for (int i = 0; i < Grafo.length; i++) {
            //System.out.printf("Ponto %d :| ", i+1);
            intAux = i + 1;
            Aux += "Vertice " + intAux.toString() + " :| ";
            for (int j = 0; j < Grafo.length; j++) {
                //System.out.printf("%d | ", Grafo[i][j]);
                intAux = Grafo[i][j];
                Aux += intAux.toString() + " | ";
            }
            //System.out.println();
            Aux += "\n";
        }
        return Aux;
    }
    /* */

    /**
     * Create a edge between two vertex. It's needed to say if the Graph is or
     * isn't oriented.
     *
     * @param a first vertex.
     * @param b second vertex.
     * @param GO boolean to know if the graph is non-oriented or oriented
     */
    public void aresta(int a, int b, boolean GO) {
        if (GO == false && a > 0 && b > 0) {
            Grafo[a - 1][b - 1] = 1;
            Grafo[b - 1][a - 1] = 1;
            m++;
        } else {
            if (a != -1 && b != -1 && GO == true) {
                Grafo[a - 1][b - 1] = 1;
                m++;
            }
        }
        if (GO == true) {
            go = true;
        }
    }

    /**
     * Returns a boolean to know if the graph is oriented or non-oriented
     *
     * @return the boolean go from this class.
     */
    public boolean isGO() {
        return go;
    }

    /**
     * reset vector cor to 'B', B means branco, in english white.
     */
    public void toWhite() {
        for (int i = 0; i < cor.length; i++) {
            cor[i] = 'B';
        }
    }

    /**
     * It says if two vertex are adjacents
     *
     * @param a first vertex.
     * @param b second vertex.
     * @return true if they are adjacents.
     */
    public boolean adjacente(int a, int b) {
        if (Grafo[a][b] >= 1 && Grafo[b][a] >= 1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * This method returns a vector with the visit order of a BFS.
     *
     * @param a the vertex where we'll begin the search.
     * @return a vector with the visit order.
     */
    public int[] BFS(int a) {
        int fila[] = new int[cor.length];
        int matriz[][] = Grafo;
        int iF = 0;//Inicio Fila
        int fF = 0;//Final Fila
        toWhite();
        cor[a - 1] = 'C';
        fila[iF] = a - 1;
        fF++;
        for (int i = 0; i < fF; i++) {
            for (int j = 0; j < Grafo.length; j++) {
                if (matriz[fila[iF]][j] == 1 && cor[j] == 'B') {
                    cor[j] = 'C';
                    fila[fF] = j;
                    fF++;
                }
            }
            cor[fila[iF]] = 'P';
            iF++;
        }
        return fila;
    }

    /**
     * Return the vector of chars cor. This vector is for search.
     *
     * @return the vector with the color P, B, or C.
     */

    public char[] getCor() {
        return cor;
    }

    /**
     *
     * @return The total of vertex.
     */

    public int getN() {
        return n;
    }

    /**
     * return the vector of integers corC used for coloring.
     *
     * @return the vector of colors as integers.
     */
    public int[] getcorC() {

        return corC;
    }

}
